package kubernetes

import (
	"context"
	"fmt"
	"k8s-admin/global"
	"k8s-admin/utils"
	"time"

	"k8s.io/apimachinery/pkg/util/json"

	v1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type ConfigMapList struct {
	Items []v1.ConfigMap `json:"items"`
	Total int            `json:"total"`
}

type SecretList struct {
	Items []v1.Secret `json:"items"`
	Total int         `json:"total"`
}

func (c *k8sCluster) CreteClusterConfigMap(cid, Namespace, ConfigMapData string) error {
	cache, err := utils.GetCache(cid)
	var (
		ctx    context.Context
		cancel context.CancelFunc
	)
	ctx, cancel = context.WithTimeout(context.TODO(), time.Second*10)

	defer cancel()
	if err != nil {
		return err
	} else {
		desc, err := utils.DecodeBase64(ConfigMapData)

		yaml := &v1.ConfigMap{}
		err = json.Unmarshal([]byte(desc), yaml)
		fmt.Println("yaml: ", yaml)
		_, err = cache.CoreV1().ConfigMaps(Namespace).Create(ctx, yaml, metav1.CreateOptions{})
		if err != nil {
			global.TPLogger.Error(err.Error())
			return err
		} else {
			return nil
		}
	}

}

func (c *k8sCluster) GetClusterConfigMapList(cid, Namespace string) (*ConfigMapList, error) {
	cache, err := utils.GetCache(cid)
	var (
		ctx    context.Context
		cancel context.CancelFunc
	)

	ctx, cancel = context.WithTimeout(context.TODO(), time.Second*10)

	defer cancel()
	if err != nil {
		return nil, err
	}
	list, err := cache.CoreV1().ConfigMaps(Namespace).List(ctx, metav1.ListOptions{})
	if err != nil {
		return nil, err
	}
	return &ConfigMapList{Items: list.Items, Total: len(list.Items)}, nil
}

func (c *k8sCluster) GetClusterConfigMapInfo(cid, Namespace, ConfigMapName string) (*v1.ConfigMap, error) {
	cache, err := utils.GetCache(cid)
	var (
		ctx    context.Context
		cancel context.CancelFunc
	)

	ctx, cancel = context.WithTimeout(context.TODO(), time.Second*10)

	defer cancel()
	if err != nil {
		return nil, err
	} else {
		Info, err := cache.CoreV1().ConfigMaps(Namespace).Get(ctx, ConfigMapName, metav1.GetOptions{})
		if err != nil {
			global.TPLogger.Error("GetClusterConfigMapInfo", "error", err)
			return nil, err
		} else {
			return Info, nil
		}
	}

}

func (c *k8sCluster) DeleteClusterConfigMap(cid, Namespace, ConfigMapName string) error {
	cache, err := utils.GetCache(cid)
	var (
		ctx    context.Context
		cancel context.CancelFunc
	)

	ctx, cancel = context.WithTimeout(context.TODO(), time.Second*10)

	defer cancel()
	if err != nil {
		return err
	}
	err = cache.CoreV1().ConfigMaps(Namespace).Delete(ctx, ConfigMapName, metav1.DeleteOptions{})
	if err != nil {
		global.TPLogger.Error("DeleteClusterConfigMap", "error", err)
		return err
	} else {
		return nil
	}
}

func (c *k8sCluster) UpdateClusterConfigMap(cid, Namespace, ConfigMapYaml string) error {
	cache, err := utils.GetCache(cid)
	var (
		ctx    context.Context
		cancel context.CancelFunc
	)

	ctx, cancel = context.WithTimeout(context.TODO(), time.Second*10)

	defer cancel()
	if err != nil {
		return err
	} else {
		desc, err := utils.DecodeBase64(ConfigMapYaml)

		yaml := &v1.ConfigMap{}
		err = json.Unmarshal([]byte(desc), yaml)

		_, err = cache.CoreV1().ConfigMaps(Namespace).Update(ctx, yaml, metav1.UpdateOptions{})
		if err != nil {
			global.TPLogger.Error(err.Error())
			return err
		} else {
			return nil
		}
	}
}

func (c *k8sCluster) CreteClusterSecret(cid, Namespace, Secret string) error {
	cache, err := utils.GetCache(cid)
	var (
		ctx    context.Context
		cancel context.CancelFunc
	)
	ctx, cancel = context.WithTimeout(context.TODO(), time.Second*10)

	defer cancel()
	if err != nil {
		return err
	} else {
		desc, err := utils.DecodeBase64(Secret)

		yaml := &v1.Secret{}
		err = json.Unmarshal([]byte(desc), yaml)
		fmt.Println("desc: ", desc)
		_, err = cache.CoreV1().Secrets(Namespace).Create(ctx, yaml, metav1.CreateOptions{})
		if err != nil {
			global.TPLogger.Error(err.Error())
			return err
		} else {
			return nil
		}
	}

}

func (c *k8sCluster) GetClusterSecretList(cid, Namespace string) (*SecretList, error) {
	cache, err := utils.GetCache(cid)
	var (
		ctx    context.Context
		cancel context.CancelFunc
	)

	ctx, cancel = context.WithTimeout(context.TODO(), time.Second*10)

	defer cancel()
	if err != nil {
		return nil, err
	}
	list, err := cache.CoreV1().Secrets(Namespace).List(ctx, metav1.ListOptions{})
	if err != nil {
		return nil, err
	}
	return &SecretList{Items: list.Items, Total: len(list.Items)}, nil
}

func (c *k8sCluster) GetClusterSecretInfo(cid, Namespace, SecretName string) (*v1.Secret, error) {
	cache, err := utils.GetCache(cid)
	var (
		ctx    context.Context
		cancel context.CancelFunc
	)

	ctx, cancel = context.WithTimeout(context.TODO(), time.Second*10)

	defer cancel()
	if err != nil {
		return nil, err
	} else {
		Info, err := cache.CoreV1().Secrets(Namespace).Get(ctx, SecretName, metav1.GetOptions{})
		if err != nil {
			global.TPLogger.Error("GetClusterConfigMapInfo", "error", err)
			return nil, err
		} else {
			return Info, nil
		}
	}

}

func (c *k8sCluster) DeleteClusterSecret(cid, Namespace, SecretListName string) error {
	cache, err := utils.GetCache(cid)
	var (
		ctx    context.Context
		cancel context.CancelFunc
	)

	ctx, cancel = context.WithTimeout(context.TODO(), time.Second*10)

	defer cancel()
	if err != nil {
		return err
	}
	err = cache.CoreV1().Secrets(Namespace).Delete(ctx, SecretListName, metav1.DeleteOptions{})
	if err != nil {
		global.TPLogger.Error("DeleteClusterConfigMap", "error", err)
		return err
	} else {
		return nil
	}
}

func (c *k8sCluster) UpdateClusterSecret(cid, Namespace, SecretYaml string) error {
	cache, err := utils.GetCache(cid)
	var (
		ctx    context.Context
		cancel context.CancelFunc
	)

	ctx, cancel = context.WithTimeout(context.TODO(), time.Second*10)

	defer cancel()
	if err != nil {
		return err
	} else {
		desc, err := utils.DecodeBase64(SecretYaml)

		yaml := &v1.Secret{}
		err = json.Unmarshal([]byte(desc), yaml)

		_, err = cache.CoreV1().Secrets(Namespace).Update(ctx, yaml, metav1.UpdateOptions{})
		if err != nil {
			global.TPLogger.Error(err.Error())
			return err
		} else {
			return nil
		}
	}
}
